package com.liuxinlong.modules.common.service.impl;

import com.liuxinlong.api.WeChatMessageInterface;
import com.liuxinlong.constant.ThreadLocalConstants;
import com.liuxinlong.enums.MatterSourceEnum;
import com.liuxinlong.enums.NotificationSourceEnum;
import com.liuxinlong.enums.WorkflowTypeEnum;
import com.liuxinlong.modules.common.service.WorkCenterService;
import com.liuxinlong.modules.dao.NotificationDao;
import com.liuxinlong.modules.dao.PatentProposalDao;
import com.liuxinlong.modules.dao.PatentRiskDao;
import com.liuxinlong.modules.dao.ProjectDao;
import com.liuxinlong.modules.dao.UserDao;
import com.liuxinlong.modules.dao.UserFollowDao;
import com.liuxinlong.modules.dao.UserMatterDao;
import com.liuxinlong.modules.dao.UserRoleRelationDao;
import com.liuxinlong.modules.dao.WorkFlowConfigDao;
import com.liuxinlong.modules.dao.WorkFlowDao;
import com.liuxinlong.modules.dao.WorkFlowNodeRecordDao;
import com.liuxinlong.modules.entity.Notification;
import com.liuxinlong.modules.entity.PatentProposal;
import com.liuxinlong.modules.entity.Project;
import com.liuxinlong.modules.entity.User;
import com.liuxinlong.modules.entity.UserFollow;
import com.liuxinlong.modules.entity.UserMatter;
import com.liuxinlong.modules.entity.UserRoleRelation;
import com.liuxinlong.modules.entity.WorkFlow;
import com.liuxinlong.modules.entity.WorkFlowNodeRecord;
import com.liuxinlong.modules.patent.service.PatentProposalService;
import com.liuxinlong.modules.system.service.FileManageService;
import com.liuxinlong.utils.IPUtils;
import com.liuxinlong.utils.ObjectUtils;
import com.liuxinlong.utils.ThreadlocalUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * 工作中心接口实现
 *
 * @author liuxinlong@hotwater.com.cn
 * @version 1.0.0
 * @since 2022-08-03
 */
@Service
@Slf4j
public class WorkCenterServiceImpl implements WorkCenterService {

    @Autowired
    private NotificationDao notificationDao;

    @Autowired
    private UserMatterDao userMatterDao;

    @Autowired
    private UserRoleRelationDao userRoleRelationDao;

    @Autowired
    private UserFollowDao userFollowDao;

    @Autowired
    private UserDao userDao;

    @Autowired
    private WorkFlowDao workFlowDao;

    @Autowired
    private WorkFlowConfigDao workFlowConfigDao;

    @Autowired
    private WorkFlowNodeRecordDao workFlowNodeRecordDao;

    @Autowired
    private ProjectDao projectDao;

    @Autowired
    private PatentProposalDao patentProposalDao;

    @Autowired
    private WeChatMessageInterface weChatMessageInterface;

    @Autowired
    private PatentRiskDao patentRiskDao;

    @Autowired
    private FileManageService fileManageService;

    @Autowired
    private PatentProposalService patentProposalService;

    @Override
    public Map<String, Object> queryTotalInfo() {
        User current = (User) ThreadlocalUtils.getCache(ThreadLocalConstants.USER_INFO);
        Map<String, Object> queryParam = new HashMap<>();
        queryParam.put("dealUser", current.getId());
        queryParam.put("status", 1);
        int doneNum = userMatterDao.getUserMatterCount(queryParam);
        Map<String, Object> map = new HashMap<>();
        map.put("done", doneNum);
        List<UserRoleRelation> relationList = userRoleRelationDao.queryRelationByUserId(current.getId());
        List<String> roleList = relationList.stream().map(UserRoleRelation::getRoleId).collect(Collectors.toList());
        queryParam.put("status", 0);
        int trendsNum = notificationDao.getNotificationCount(queryParam);
        map.put("trends", trendsNum);
        queryParam.put("roleList", roleList);
        queryParam.put("dealUser", null);
        queryParam.put("pendingUser", current.getId());
        int pendingNum = userMatterDao.getUserMatterCount(queryParam);
        map.put("need", pendingNum);
//        queryParam.put("status", 0);

        return map;
    }

    @Override
    public List<Map<String, Object>> queryNeedList(Map<String, Object> queryParam) {
        User current = (User) ThreadlocalUtils.getCache(ThreadLocalConstants.USER_INFO);
        queryParam.put("pendingUser", current.getId());
        queryParam.put("status", 0);
        List<UserRoleRelation> relationList = userRoleRelationDao.queryRelationByUserId(current.getId());
        List<String> roleList = relationList.stream().map(UserRoleRelation::getRoleId).collect(Collectors.toList());
        queryParam.put("roleList", roleList);
        List<UserMatter> pendingList = userMatterDao.pageUserMatter(queryParam);
        List<String> businessIdList = pendingList.stream().map(UserMatter::getSourceId).collect(Collectors.toList());
        Map<String, Project> projectMap = new HashMap<>();
        Map<String, PatentProposal> patentMap = new HashMap<>();
        Map<String, String> workFlowProjectMap = new HashMap<>();
        Map<String, String> workFlowProposalMap = new HashMap<>();
        if (!businessIdList.isEmpty()) {
            if (queryParam.containsKey("sourceType") &&
                    (int) queryParam.get("sourceType") == MatterSourceEnum.PATENT_PROJECT_INVESTIGATION.getValue()) {
                List<WorkFlow> workFlowList = workFlowDao.getWorkflowListByIds(businessIdList);
                List<String> sourceIdList = workFlowList.stream().map(WorkFlow::getBusinessId).collect(Collectors.toList());
                if (!sourceIdList.isEmpty()) {
                    List<Project> projectList = projectDao.getProjectListByIds(sourceIdList);
                    for (Project project : projectList) {
                        projectMap.put(project.getId(), project);
                    }
                    List<PatentProposal> proposalList = patentProposalDao.getProposalListByIds(sourceIdList);
                    for (PatentProposal proposal : proposalList) {
                        patentMap.put(proposal.getId(), proposal);
                    }
                }
                for (WorkFlow workFlow : workFlowList) {
                    if (projectMap.containsKey(workFlow.getBusinessId())) {
                        workFlowProjectMap.put(workFlow.getId(), workFlow.getBusinessId());
                    } else if (patentMap.containsKey(workFlow.getBusinessId())) {
                        workFlowProposalMap.put(workFlow.getId(), workFlow.getBusinessId());
                    }
                }
            }
        }
        List<Map<String, Object>> needList = new ArrayList<>();
        int sort = 1;
        for (UserMatter item : pendingList) {
            Map<String, Object> pendingMap = ObjectUtils.object2Map(item);
            pendingMap.put("sort", sort);
            pendingMap.put("sourceName", MatterSourceEnum.getNameByValue(item.getSourceType()));
            pendingMap.put("businessTypeName", MatterSourceEnum.getNameByValue(item.getSourceType()));
            List<String> contentList = Arrays.asList(item.getContent().split("，")[0].split("发起"));
            if (contentList.size() == 2) {
                if (workFlowProjectMap.containsKey(item.getSourceId())) {
                    pendingMap.put("content", contentList.get(0) + "发起 { " + projectMap.get(workFlowProjectMap.get(item.getSourceId())).getProjectName() + " } " + contentList.get(1));
                } else if (workFlowProposalMap.containsKey(item.getSourceId())) {
                    pendingMap.put("content", contentList.get(0) + "发起 { " + patentMap.get(workFlowProposalMap.get(item.getSourceId())).getOpenSn() + " - " + patentMap.get(workFlowProposalMap.get(item.getSourceId())).getPatentName() + " } " + contentList.get(1));
                }
            }
            needList.add(pendingMap);
            sort++;
        }
        return needList;
    }

    @Override
    public List<Map<String, Object>> queryDoneList(Map<String, Object> queryParam) {
        User current = (User) ThreadlocalUtils.getCache(ThreadLocalConstants.USER_INFO);
        queryParam.put("dealUser", current.getId());
        queryParam.put("status", 1);
        List<UserMatter> doneList = userMatterDao.pageUserMatter(queryParam);
        List<String> businessIdList = doneList.stream().map(UserMatter::getSourceId).collect(Collectors.toList());
        Map<String, Project> projectMap = new HashMap<>();
        Map<String, PatentProposal> patentMap = new HashMap<>();
        Map<String, String> workFlowProjectMap = new HashMap<>();
        Map<String, String> workFlowProposalMap = new HashMap<>();
        if (!businessIdList.isEmpty()) {
            if (queryParam.containsKey("sourceType") && (int) queryParam.get("sourceType") == MatterSourceEnum.PATENT_PROJECT_INVESTIGATION.getValue()) {
                List<WorkFlow> workFlowList = workFlowDao.getWorkflowListByIds(businessIdList);
                List<String> sourceIdList = workFlowList.stream().map(WorkFlow::getBusinessId).collect(Collectors.toList());
                if (!sourceIdList.isEmpty()) {
                    List<Project> projectList = projectDao.getProjectListByIds(sourceIdList);
                    for (Project project : projectList) {
                        projectMap.put(project.getId(), project);
                    }
                    List<PatentProposal> proposalList = patentProposalDao.getProposalListByIds(sourceIdList);
                    for (PatentProposal proposal : proposalList) {
                        patentMap.put(proposal.getId(), proposal);
                    }
                }
                for (WorkFlow workFlow : workFlowList) {
                    if (projectMap.containsKey(workFlow.getBusinessId())) {
                        workFlowProjectMap.put(workFlow.getId(), workFlow.getBusinessId());
                    } else if (patentMap.containsKey(workFlow.getBusinessId())) {
                        workFlowProposalMap.put(workFlow.getId(), workFlow.getBusinessId());
                    }
                }
            }
        }
        List<Map<String, Object>> resultList = new ArrayList<>();
        int sort = 1;
        for (UserMatter item : doneList) {
            Map<String, Object> doneMap = ObjectUtils.object2Map(item);
            doneMap.put("sort", sort);
            doneMap.put("sourceName", MatterSourceEnum.getNameByValue(item.getSourceType()));
            doneMap.put("businessTypeName", MatterSourceEnum.getNameByValue(item.getSourceType()));
            List<String> contentList = Arrays.asList(item.getContent().split("，")[0].split("发起"));
            if (contentList.size() == 2 && workFlowProjectMap.containsKey(item.getSourceId())) {
                doneMap.put("content", contentList.get(0) + "发起 { " + projectMap.get(workFlowProjectMap.get(item.getSourceId())).getProjectName() + " } " + contentList.get(1));
            }else if (workFlowProposalMap.containsKey(item.getSourceId())) {
                doneMap.put("content", contentList.get(0) + "发起 { " + patentMap.get(workFlowProposalMap.get(item.getSourceId())).getOpenSn() + " - " + patentMap.get(workFlowProposalMap.get(item.getSourceId())).getPatentName() + " } " + contentList.get(1));
            }
            resultList.add(doneMap);
            sort++;
        }
        return resultList;
    }

    @Override
    public List<Map<String, Object>> queryTrendsList(Map<String, Object> queryParam) {
        List<Notification> notificationList = notificationDao.pageNotification(queryParam);
        List<Map<String, Object>> trendsList = new ArrayList<>();
        int sort = 1;
        for (Notification item : notificationList) {
            Map<String, Object> trendsMap = ObjectUtils.object2Map(item);
            trendsMap.put("sourceName", NotificationSourceEnum.getSourceNameByValue(item.getSourceType()));
            trendsMap.put("sort", sort);
            trendsMap.put("read", item.getStatus() == 1 ? true : false);
            trendsList.add(trendsMap);
            sort++;
        }
        return trendsList;
    }

    @Override
    public int getTrendsCount(Map<String, Object> queryParam) {
        return notificationDao.getNotificationCount(queryParam);
    }

    @Override
    public List<Map<String, Object>> queryFollowList(Map<String, Object> queryParam) {
        List<UserFollow> userFollowList = userFollowDao.getUserFollowList(queryParam);
        List<Map<String, Object>> resultList = new ArrayList<>(userFollowList.size());
        Map<String, Map<String, String>> userMap = userDao.getUserPictureMap();
        String currentIp = IPUtils.getCurrentIp();
        int sort = (int) queryParam.get("startNum") + 1;
        for (UserFollow userFollow : userFollowList) {
            Map<String, Object> item = ObjectUtils.object2Map(userFollow);
            item.put("sort", sort);
            if (userMap.containsKey(userFollow.getFollowId())) {
                Map<String, String> data = userMap.get(userFollow.getFollowId());
                item.put("followName", data.get("name"));
                item.put("image", data.containsKey("portrait") ? data.get("filePath").replace("upload", "http:\\\\" + currentIp + ":8090\\preview\\upload") : "");
            }
            resultList.add(item);
        }
        return resultList;
    }

    @Override
    public int getFollowCount(Map<String, Object> queryParam) {
        return userFollowDao.getUserFollowCount(queryParam);
    }

    @Override
    public List<Map<String, Object>> queryFansList(Map<String, Object> queryParam) {
        List<UserFollow> userFansList = userFollowDao.getUserFansList(queryParam);
        List<Map<String, Object>> resultList = new ArrayList<>(userFansList.size());
        Map<String, Map<String, String>> userMap = userDao.getUserPictureMap();
        String currentIp = IPUtils.getCurrentIp();
        List<UserFollow> userFollowList = userFollowDao.getUserFollowList(queryParam);
        Map<String, UserFollow> followMap = new HashMap<>(userFollowList.size());
        for (UserFollow userFollow : userFollowList) {
            followMap.put(userFollow.getFollowId(), userFollow);
        }
        int sort = (int) queryParam.get("startNum") + 1;
        for (UserFollow userFollow : userFansList) {
            Map<String, Object> item = ObjectUtils.object2Map(userFollow);
            item.put("sort", sort);
            if (userMap.containsKey(userFollow.getUserId())) {
                Map<String, String> data = userMap.get(userFollow.getUserId());
                item.put("fansName", data.get("name"));
                item.put("image", data.containsKey("portrait") ? data.get("filePath").replace("upload", "http:\\\\" + currentIp + ":8090\\preview\\upload") : "");
            }
            item.put("followFlag", followMap.containsKey(userFollow.getUserId()));
            resultList.add(item);
        }
        return resultList;
    }

    @Override
    public int getFansCount(Map<String, Object> queryParam) {
        return userFollowDao.getUserFansCount(queryParam);
    }

    @Override
    public List<Map<String, Object>> queryWorkflowApplyList(Map<String, Object> queryParam) {
        List<WorkFlow> workflowList = workFlowDao.pageWorkflowList(queryParam);
        List<String> businessIdList = workflowList.stream().map(WorkFlow::getBusinessId).collect(Collectors.toList());
        // 项目列表
        Map<String, Project> projectMap = new HashMap<>();
        if (!businessIdList.isEmpty()) {
            List<Project> projectList = projectDao.getProjectListByIds(businessIdList);
            for (Project project : projectList) {
                projectMap.put(project.getId(), project);
            }
        }
        // 专利列表
        Map<String, PatentProposal> patentMap = new HashMap<>();
        if (!businessIdList.isEmpty()) {
            List<PatentProposal> proposalList = patentProposalDao.getProposalListByIds(businessIdList);
            for (PatentProposal proposal : proposalList) {
                patentMap.put(proposal.getId(), proposal);
            }
        }
        Map<String, Map<String, Object>> workflowConfigMap = workFlowConfigDao.getWorkflowConfigMap();
        List<Map<String, Object>> resultList = new ArrayList<>(workflowList.size());
        int sort = (int) queryParam.get("startNum") + 1;
        for (WorkFlow workFlow : workflowList) {
            Map<String, Object> item = ObjectUtils.object2Map(workFlow);
            item.put("sort", sort);
            if (workflowConfigMap.containsKey(workFlow.getConfigId())) {
                Map<String, Object> configMap = workflowConfigMap.get(workFlow.getConfigId());
                item.put("sourceName", configMap.get("name"));
//                item.put("content", JSONObject.parse(workFlow.getContent()));
                int businessType = (int) configMap.get("businessType");
                item.put("businessType", businessType);
                item.put("businessTypeName", WorkflowTypeEnum.getNameByValue(businessType));
                String content;
//                item.put("content", WorkflowTypeEnum.getNameByValue(businessType));
                if (businessType == WorkflowTypeEnum.PATENT_INVESTIGATION.getValue() || businessType == WorkflowTypeEnum.PATENT_RISK_ANALYSIS.getValue()) {
                    Project project = projectMap.get(workFlow.getBusinessId());
                    content = "项目 {" + project.getProjectName() + " } 发起" +
                            (businessType == WorkflowTypeEnum.PATENT_INVESTIGATION.getValue() ? "项目风险排查" :
                                    businessType == WorkflowTypeEnum.PATENT_RISK_ANALYSIS.getValue() ? "新品专利风险分析" : "")
                            + "需求";
                    item.put("content", content);
                } else if (businessType == WorkflowTypeEnum.PATENT_RISK.getValue()) {
                    PatentProposal proposal = patentMap.get(workFlow.getBusinessId());
                    content = "专利 {" + proposal.getOpenSn() + " - " + proposal.getPatentName() + " } 发起风险专利评估需求";
                    item.put("content", content);
                }
            }
            resultList.add(item);
            sort++;
        }
        return resultList;
    }

    @Override
    public int getWorkflowApplyCount(Map<String, Object> queryParam) {
        return workFlowDao.getWorkflowCount(queryParam);
    }

    @Override
    public List<Map<String, Object>> queryWorkflowCCList(Map<String, Object> queryParam) {
        return null;
    }

    @Override
    public int getWorkflowCCCount(Map<String, Object> queryParam) {
        return 0;
    }

    @Override
    public List<Map<String, Object>> queryWorkflowAllList(Map<String, Object> queryParam) {
        User current = (User) ThreadlocalUtils.getCache(ThreadLocalConstants.USER_INFO);
        queryParam.put("dealUser", current.getId());
        List<WorkFlowNodeRecord> recordList = workFlowNodeRecordDao.getWorkflowByDealUser(current.getId());
//        Map<String,String> recordMap = new HashMap<>();
        Set<String> recordSet = new HashSet<>();
        for (WorkFlowNodeRecord record : recordList) {
            recordSet.add(record.getWorkflowId());
//            recordMap.put(record.getWorkflowId(),record.getWorkflowId());
        }
        List<WorkFlow> workFlowList = recordSet.size() == 0 ? new ArrayList<>() : workFlowDao.selectBatchIds(recordSet);
        List<String> businessIdList = workFlowList.stream().map(WorkFlow::getBusinessId).collect(Collectors.toList());
        // 项目列表
        Map<String, Project> projectMap = new HashMap<>();
        if (!businessIdList.isEmpty()) {
            List<Project> projectList = projectDao.getProjectListByIds(businessIdList);
            for (Project project : projectList) {
                projectMap.put(project.getId(), project);
            }
        }
        // 专利列表
        Map<String, PatentProposal> patentMap = new HashMap<>();
        if (!businessIdList.isEmpty()) {
            List<PatentProposal> proposalList = patentProposalDao.getProposalListByIds(businessIdList);
            for (PatentProposal proposal : proposalList) {
                patentMap.put(proposal.getId(), proposal);
            }
        }
        List<WorkFlow> sortedWorkFlowList = workFlowList.stream().sorted(Comparator.nullsLast(Comparator.comparing(WorkFlow::getCreateTime,
                Comparator.nullsLast(Comparator.reverseOrder())))).collect(Collectors.toList());
        List<Map<String, Object>> resultList = new ArrayList<>();
        Map<String, Map<String, Object>> workflowConfigMap = workFlowConfigDao.getWorkflowConfigMap();
        Map<String, Map<String, String>> userMap = userDao.getUserMap();
        for (WorkFlow workFlow : sortedWorkFlowList) {
            Map<String, Object> item = ObjectUtils.object2Map(workFlow);
            if (workflowConfigMap.containsKey(workFlow.getConfigId())) {
                Map<String, Object> configMap = workflowConfigMap.get(workFlow.getConfigId());
                item.put("sourceName", configMap.get("name"));
                int businessType = (int) configMap.get("businessType");
                item.put("businessType", businessType);
                item.put("businessTypeName", WorkflowTypeEnum.getNameByValue(businessType));
                String content;
                boolean createFlag = StringUtils.equals(current.getId(), workFlow.getCreateUser());
                if (businessType == WorkflowTypeEnum.PATENT_INVESTIGATION.getValue() || businessType == WorkflowTypeEnum.PATENT_RISK_ANALYSIS.getValue()) {
                    Project project = projectMap.get(workFlow.getBusinessId());

                    content = (createFlag ? "" : "用户 {" + userMap.get(workFlow.getCreateUser()).get("name") + "},") +
                            "项目 {" + project.getProjectName() + " } 发起" +
                            (businessType == WorkflowTypeEnum.PATENT_INVESTIGATION.getValue() ? "项目风险排查" :
                                    businessType == WorkflowTypeEnum.PATENT_RISK_ANALYSIS.getValue() ? "新品专利风险分析" : "")
                            + "需求";
                    item.put("content", content);
                } else if (businessType == WorkflowTypeEnum.PATENT_RISK.getValue()) {
                    PatentProposal proposal = patentMap.get(workFlow.getBusinessId());
                    content = (createFlag ? "" : "用户 {" + userMap.get(workFlow.getCreateUser()).get("name") + "},") +
                            "专利 {" + proposal.getOpenSn() + " - " + proposal.getPatentName() + " } 发起风险专利评估需求";
                    item.put("content", content);
                }
            }

            resultList.add(item);
        }

        return resultList;
    }

    @Override
    public int getWorkflowAllCount(Map<String, Object> queryParam) {
        return workFlowNodeRecordDao.getWorkflowAllCount(queryParam);
    }

}
